# -*- coding: utf-8 -*-
# @Date：2024/7/30 10:24:01
# @Author：CJiaの青姝
# @FileName：dict
# @Editor：PyCharm2024
# @Remark：
from typing import List, Any
from typing_extensions import Self

from data.models import Dict
from ninja import Router, Field, File, Query, ModelSchema
from ninja import Router
from ninja.files import UploadedFile
from ninja.pagination import paginate

from utils.cj_ninja import CjFilters, MyPagination
from utils.cj_crud import create, batch_create, delete, batch_delete, update, condition, single
from utils.cj_export import export_data, repeat_data, deal_chinese_key
from utils.cj_response import SuccessResponse, ErrorResponse

router = Router()


class Filters(CjFilters):
    name: str = Field(None, description="字典名称", alias='name')
    code: str = Field(None, description="字典编码", alias='code')

    class Config:
        title = "字典查询参数"


class DictSchemaIn(ModelSchema):

    def validate(cls, value: Any) -> Self:
        if value.name == '' or value.name is None:
            return "字典名称不能为空", 400
        elif value.code == '' or value.code is None:
            return "字典编码不能为空", 400
        # 返回请求数据
        return value, 200

    def model_validate(
            cls,
            obj: Any,
            *,
            strict: bool | None = None,
            from_attributes: bool | None = None,
            context: Any | None = None,
    ) -> Self:
        if obj.name == '' or obj.name is None:
            return "字典名称不能为空", 400
        elif obj.code == '' or obj.code is None:
            return "字典编码不能为空", 400
        # 判断重复
        if Dict.objects.filter(name=obj.name).exists():
            return "字典名称已存在，请重新输入", 400
        if Dict.objects.filter(code=obj.code).exists():
            return "字典编码已存在，请重新输入", 400
        # 返回请求数据
        return obj, 200

    class Config:
        title = '创建字典参数'
        model = Dict
        model_exclude = ['id', 'creator', 'modifier', 'create_time', 'update_time']


class DictSchemaOut(ModelSchema):
    key: int = Field(None, description="唯一标识符", alias='key')

    class Config:
        title = '字典对象实例'
        model = Dict
        model_fields = "__all__"


@router.post("/dict", summary="创建字典")
def create_dict(request, data: DictSchemaIn):
    """ 创建字典 """
    message, code = data.model_validate(data)
    if code == 400:
        return ErrorResponse(msg=message)
    # 调用新增方法
    result = create(request, Dict, message)
    # 返回结果
    return SuccessResponse(data=result, msg="新增成功")


@router.post("/dict/export", summary="导入字典")
def export_dict(request, file: UploadedFile = File(...)):
    """ 导入字典 """
    # 字段关系
    field_relations = {
        "字典名称": "name",
        "字典编码": "code",
    }
    # 检查字段
    check_list = ["字典名称", "字典编码"]
    # 调用公共导入方法
    export_result = export_data(request, file, check_list)
    # 重复字段
    repeat_filed = [
        {"name": "字典名称", "field": "name", "model": "name"},
        {"name": "字典编码", "field": "code", "model": "code"},
    ]
    # 判断重复
    result = repeat_data(Dict, export_result['success'], repeat_filed, False)
    # 处理中文key
    result = deal_chinese_key(result, field_relations)
    # 调用批量新增方法
    result_list = batch_create(request, Dict, result['success'])
    Dict.objects.bulk_create(result_list)
    message = f"成功导入{len(result_list)}条数据，失败信息{export_result['error'] + result['error']}"
    # 返回结果
    return SuccessResponse(data=result['success'], msg=message)


@router.delete("/dict/{dict_id}", response=DictSchemaOut, summary="删除字典")
def delete_dict(request, dict_id: int):
    """ 删除字典 """
    # 调用删除方法
    result, code = delete(Dict, dict_id)
    if code != 200:
        return ErrorResponse(code=code, msg=result)
    # 返回结果
    return SuccessResponse(data=result, msg="删除成功")


@router.delete("/dict/batch/del", summary="批量删除字典")
def batch_delete_dict(request, ids: List[int]):
    """ 批量删除字典 """
    # 调用批量删除方法
    result = batch_delete(request, Dict, ids)
    # 返回结果
    return SuccessResponse(data=result, msg="批量删除成功")


@router.put("/dict/{dict_id}", response=DictSchemaOut, summary="更新字典")
def update_dict(request, dict_id: int, data: DictSchemaIn):
    """ 更新字典 """
    message, code = data.validate(data)
    if code == 400:
        return ErrorResponse(msg=message)
    # 判断重复
    if Dict.objects.filter(name=message.name).exclude(id=dict_id).exists():
        return ErrorResponse(msg="字典名称已存在，请重新输入")
    if Dict.objects.filter(code=message.code).exclude(id=dict_id).exists():
        return ErrorResponse(msg="字典编码已存在，请重新输入")
    # 调用修改方法
    result = update(request, Dict, message, dict_id)
    # 返回结果
    return SuccessResponse(data=result, msg="更新成功")


@router.get("/dict", response=List[DictSchemaOut], summary="获取分页字典列表")
@paginate(MyPagination)
def list_dict(request, filters: Filters = Query(...)):
    """获取分页字典列表"""
    # 调用分页方法
    result = condition(request, Dict, filters)
    # 返回结果
    return result


@router.get("/dict/tree/list", response=List[DictSchemaOut], summary="获取字典列表树")
def list_dict_tree(request, filters: Filters = Query(...)):
    """获取字典列表树"""
    # 调用查询集方法 - 将查询集转换成树形结构
    result = condition(request, Dict, filters)
    # 返回结果
    return SuccessResponse(data=result)


@router.get("/dict/{dict_id}", response=DictSchemaOut, summary="获取字典")
def get_dict(request, dict_id: int):
    """ 获取字典 """
    # 调用根据id获取指定对象方法
    result = single(request, Dict, id=dict_id)
    # 返回结果
    return SuccessResponse(data=result)
